<script setup lang="ts">
import { ref, computed } from "vue";
import ColorPanel from "../color-panel/color-panel.vue";
import { FormModel } from "../../types/FormModel";

interface ColorPickerProps {
  disabled?: boolean;
  trigger?: "click" | "hover" | "focus" | "contextmenu";
  placement?:
    | "top"
    | "top-start"
    | "top-end"
    | "bottom"
    | "bottom-start"
    | "bottom-end"
    | "left"
    | "left-start"
    | "left-end"
    | "right"
    | "right-start"
    | "right-end";
  teleported?: boolean;
  panelWidth?: string | number;
  panelHeight?: string | number;
  showOpacity?: boolean;
  showHistory?: boolean;
  blockSize?: number | string;
  formModel?: FormModel;
}

const props = withDefaults(defineProps<ColorPickerProps>(), {
  disabled: false,
  trigger: "click",
  placement: "bottom-start",
  teleported: true,
  panelHeight: "360px",
  showOpacity: true,
  showHistory: false,
  blockSize: 24,
});

const emit = defineEmits<{
  (e: "change", value: string): void;
  (e: "confirm", value: string): void;
  (e: "visible-change", visible: boolean): void;
}>();

const colorValue = defineModel<string>({ default: "#000000" });
const visible = ref(false);

const normalizedBlockSize = computed(() => {
  return typeof props.blockSize === "number"
    ? `${props.blockSize}px`
    : props.blockSize;
});

function handleChange(val: string) {
  colorValue.value = val;
  emit("change", val);
}

function handleConfirm(val: string) {
  colorValue.value = val;
  emit("confirm", val);
  visible.value = false;
}
</script>

<template>
  <el-popover
    v-model:visible="visible"
    :placement="placement"
    :trigger="trigger"
    :disabled="disabled"
    :teleported="teleported"
    width="fit-content"
    @show="emit('visible-change', true)"
    @hide="emit('visible-change', false)"
  >
    <template #reference>
      <div
        class="color-block"
        :class="{ disabled }"
        :style="{
          width: normalizedBlockSize,
          height: normalizedBlockSize,
          backgroundColor: colorValue || '#ffffff',
        }"
      />
    </template>

    <ColorPanel
      v-model="colorValue"
      :show-opacity="showOpacity"
      :show-history="showHistory"
      :width="panelWidth"
      :height="panelHeight"
      @change="handleChange"
      @confirm="handleConfirm"
    />
  </el-popover>
</template>

<style scoped>
.color-block {
  display: inline-block;
  border-radius: 4px;
  border: 1px solid rgba(0, 0, 0, 0.15);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05) inset;
  cursor: pointer;
}
.color-block.disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
</style>
